package com.springboot.file.oss;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectMetadata;
import com.springboot.file.FileException;
import com.springboot.file.filebase.IFileStorageInterface;
import com.springboot.file.filedto.MultipartFileDto;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Date;

/**
 * @Classname OssStorageService
 * @Description TODO
 * @Version 1.0.0
 * @Date 2024/1/11 16:42
 * @Created by zyj
 */
@Component
public class OssStorageService implements IFileStorageInterface {

    @Value("${oss.accesskeysecret:test}")
    private  String accessKeySecret;

    @Value("${oss.accesskeyid:test}")
    private  String accessKeyId;

    @Value("${oss.endpoint:test}")
    private  String endpoint;

    @Value("${oss.bucketName:test}")
    private  String bucketName;

    @Value("${oss.dictionary:test}")
    private  String dictionary;


    @Value("${oss.timeOut:test}")
    private  String timeOut;

    @Value("${oss.bucketImgUrl:test}")
    private String bucketImgUrl;


    @Value("${oss.myFileUrl:test}")
    private String myFileUrl;


    @Override
    public String uploadMultipartFile(MultipartFileDto multipartFileDto) throws FileException {
        MultipartFile multipartFile = multipartFileDto.getMultipartFile();
        String myDictionary = multipartFileDto.getDictionary();
        if(!StringUtils.isEmpty(myDictionary)){
            dictionary = myDictionary;
        }
        String fileName = multipartFile.getName();
        String fileType = FilenameUtils.getExtension(multipartFile.getOriginalFilename());
        String fullPathName = dictionary+"/"+fileName;
        OSS ossClient = this.getOssClient();
        try {
            //创建上传Object的Metadata
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(multipartFile.getSize());
            metadata.setCacheControl("no-cache");
            metadata.setHeader("Pragma", "no-cache");
            metadata.setContentEncoding("utf-8");
            metadata.setContentType(contentType(fileType));
            metadata.setContentDisposition("inline;filename=" + fileName);
            ossClient.putObject(bucketName, fullPathName, multipartFile.getInputStream(), metadata);
            return fullPathName;
        } catch (IOException e) {
            throw new FileException("oss上传文件失败", e);
        }
    }

    @Override
    public byte[] downloadFile(String filePath) throws FileException {
        OSS ossClient = this.getOssClient();
        try {
            OSSObject object = ossClient.getObject(bucketName, URLDecoder.decode(filePath, "utf-8"));
            // 获取Object的输入流
            InputStream input = object.getObjectContent();
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            byte[] buffer = new byte[4096];
            int n = 0;
            while (-1 != (n = input.read(buffer))) {
                output.write(buffer, 0, n);
            }
            return output.toByteArray();
        } catch (Exception e) {
            throw new FileException("oss 下载文件失败", e);
        }

    }

    @Override
    public boolean deleteFile(String filePath) throws FileException {
        OSS ossClient = this.getOssClient();
        ossClient.deleteObject(bucketName, filePath);
        return true;
    }

    @Override
    public String getFileLink(String filePath) throws FileException {
        OSS ossClient = null;
        try {
            ossClient = this.getOssClient();
            URL url = ossClient.generatePresignedUrl(bucketName, filePath, new Date(System.currentTimeMillis() + timeOut));
            if (!StringUtils.isEmpty(url) && !StringUtils.isEmpty(myFileUrl)) {
                //域名替换为自己的
                return url.toString().replace(bucketImgUrl, myFileUrl);
            }
            return null;
        } catch (Exception e) {
            throw new FileException("获取oss 文件链接失败", e);
        } finally {
            //关闭OSSClient
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    @Override
    public String getDomain() {
        return myFileUrl;
    }

    public OSS getOssClient() {
        return new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    }

    /**
     * Description: 判断OSS服务文件上传时文件的contentType
     * @Version1.0
     * @param FilenameExtension 文件后缀
     * @return String
     */
    public String contentType(String FilenameExtension){
        if(FilenameExtension.equals("BMP")||FilenameExtension.equals("bmp")){return "image/bmp";}
        if(FilenameExtension.equals("GIF")||FilenameExtension.equals("gif")){return "image/gif";}
        if(FilenameExtension.equals("JPEG")||FilenameExtension.equals("jpeg")||
                FilenameExtension.equals("JPG")||FilenameExtension.equals("jpg")||
                FilenameExtension.equals("PNG")||FilenameExtension.equals("png")){return "image/jpeg";}
        if(FilenameExtension.equals("HTML")||FilenameExtension.equals("html")){return "text/html";}
        if(FilenameExtension.equals("TXT")||FilenameExtension.equals("txt")){return "text/plain";}
        if(FilenameExtension.equals("VSD")||FilenameExtension.equals("vsd")){return "application/vnd.visio";}
        if(FilenameExtension.equals("PPTX")||FilenameExtension.equals("pptx")||
                FilenameExtension.equals("PPT")||FilenameExtension.equals("ppt")){return "application/vnd.ms-powerpoint";}
        if(FilenameExtension.equals("DOCX")||FilenameExtension.equals("docx")||
                FilenameExtension.equals("DOC")||FilenameExtension.equals("doc")){return "application/msword";}
        if(FilenameExtension.equals("XML")||FilenameExtension.equals("xml")){return "text/xml";}
        if (FilenameExtension.equalsIgnoreCase("xlsx")|| FilenameExtension.equalsIgnoreCase("xls")){return "application/vnd.ms-excel";}
        return "text/html";
    }
}
